package com.yj.question_project.service;

import com.yj.question_project.domain.LineStation;
import com.yj.question_project.domain.MetroLine;
import com.yj.question_project.domain.StationEdge;
import com.yj.question_project.domain.VNode;
import com.yj.question_project.mapper.LineStationMapper;
import com.yj.question_project.mapper.MetroLineMapper;
import com.yj.question_project.mapper.StationEdgeMapper;
import com.yj.question_project.mapper.VNodeMapper;
import com.yj.question_project.utils.NodeUtils;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.ApplicationArguments;
import org.springframework.boot.ApplicationRunner;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.stream.Collectors;

/**
 * @Auther: starsky1
 * @Date: 2024/01/11 17:37
 * @Description: todo
 */
@Service
@Slf4j
public class Ques4Service implements ApplicationRunner {
    @Autowired
    private VNodeMapper vNodeMapper;
    @Autowired
    private LineStationMapper lineStationMapper;
    @Autowired
    private MetroLineMapper metroLineMapper;
    @Autowired
    private StationEdgeMapper stationEdgeMapper;

    @Override
    @Transactional(rollbackFor = Throwable.class)
    public void run(ApplicationArguments args) throws Exception {
        log.info("初始化站点数据...");
        // 判断数据库是否有节点数据
        boolean flag = false;
        final int cnt = vNodeMapper.countVNodes();
        if(cnt > 0) {
            flag = true;
        }
        if(!flag) {
            // 初始化数据库
            Map<Integer, VNode> stationMap = new HashMap<>(50);
            Map<String, Integer> stationIdMap = new HashMap<>(50);
            Map<String, MetroLine> lineMap = new LinkedHashMap<>(20);
            NodeUtils.initData(stationMap, stationIdMap, lineMap);
            // 初始化 线路数据
            List<MetroLine> lineList = new ArrayList<>(new HashSet<>(lineMap.values()));
            metroLineMapper.batchInsert(lineList);
            // 初始化 站点数据
            Set<VNode> nodes = new HashSet<>();
            int y = -2000;
            for (MetroLine line : lineMap.values()) {
                int x = -5000;
                for (VNode node : line.getStations()) {
                    node.setStaColor(line.getLineColor());
                    if(node.getBelongLines().size()>1) {
                        node.setStaType(1);
                    } else {
                        node.setStaType(0);
                    }
                    node.setX(x);
                    x+=1000;
                    node.setY(y);
                    nodes.add(node);
                }
                y+=1000;
            }
            vNodeMapper.batchInsert(nodes.stream().collect(Collectors.toList()));
            // 初始化 站点和线路对应关系
            List<LineStation> lsList = new ArrayList<>();
            for (VNode node : nodes) {
                for (MetroLine line : node.getBelongLines()) {
                    final LineStation lineStation = LineStation.builder()
                            .lineId(line.getLineId())
                            .staId(node.getStaId()).build();
                    lsList.add(lineStation);
                }
            }
            lineStationMapper.batchInsert(lsList);
            // 初始化 站点之间边数据
            List<StationEdge> edgeList = new ArrayList<>();
            for (VNode node : nodes) {
                for (VNode neighbor : node.getRelateNodes()) {
                    final StationEdge edge = StationEdge.builder()
                            .sourceStaId(node.getStaId())
                            .targetStaId(neighbor.getStaId()).build();
                    edgeList.add(edge);
                }
            }
            stationEdgeMapper.batchInsert(edgeList);
        }
        log.info("初始化站点数据... done");
    }

    public List<VNode> selectAllVNode() {
        return vNodeMapper.selectList(VNode.builder().build());
    }

    public List<StationEdge> selectAllEdges() {
        return stationEdgeMapper.selectList(StationEdge.builder().build());
    }
}
